const express = require("express");
const router = express.Router();
const EPub = require("epub");
const { pool, redisClient } = require("../config/db");
const { verifyAdmin } = require("../middleware/auth");
const { upload, fileSizeLimit } = require("../utils/fileHandler");

const {
  extractCoverFromEpub,
  parseEpub,
  getChapterContent,
} = require("../utils/epubHandler");
const { formatBookTypes, formatBookData } = require("../utils/formatter");

// 获取所有电子书类型
router.get("/types", async (req, res) => {
  try {
    const [rows] = await pool.execute("SELECT * FROM book_types");
    res.json({
      code: 200,
      data: formatBookTypes(rows),
    });
  } catch (error) {
    console.error("获取电子书类型失败:", error);
    res.status(500).json({
      code: 500,
      message: "获取电子书类型失败",
    });
  }
});

// 上传电子书（需要管理员权限）
router.post(
  "/",
  upload.fields([{ name: "epub", maxCount: 1 }]),
  verifyAdmin,
  fileSizeLimit,
  async (req, res) => {
    const conn = await pool.getConnection();
    let epubPath = null;
    let coverPath = null;
    try {
      const {
        title,
        author,
        publisher,
        publishDate,
        description,
        typeId,
        isRecommended,
      } = req.body;

      // 打印请求体和文件信息，便于排查问题
      console.log("上传电子书参数 req.body:", req.body);
      console.log("上传电子书文件 req.files:", req.files);

      // 验证必填字段和字段长度
      if (!title || !author || !typeId) {
        return res.status(400).json({
          code: 400,
          message: "标题、作者和类型是必填项",
        });
      }

      // 验证字段长度
      if (title.length > 100) {
        return res.status(400).json({
          code: 400,
          message: "标题长度不能超过100个字符",
        });
      }

      if (author.length > 50) {
        return res.status(400).json({
          code: 400,
          message: "作者长度不能超过50个字符",
        });
      }

      if (publisher && publisher.length > 100) {
        return res.status(400).json({
          code: 400,
          message: "出版社长度不能超过100个字符",
        });
      }

      if (description && description.length > 500) {
        return res.status(400).json({
          code: 400,
          message: "简介长度不能超过500个字符",
        });
      }

      // 验证文件上传
      if (!req.files.epub) {
        return res.status(400).json({
          code: 400,
          message: "电子书文件是必需的",
        });
      }

      epubPath = req.files.epub[0].path;
      coverPath = req.files.cover ? req.files.cover[0].path : null;

      // 验证epub文件的完整性并提取封面
      try {
        await parseEpub(epubPath);

        // 尝试从epub中提取封面图片
        if (!coverPath) {
          coverPath = await extractCoverFromEpub(new EPub(epubPath));
        }
      } catch (error) {
        throw new Error("无效的epub文件格式");
      }

      // 开始事务
      await conn.beginTransaction();

      // 插入数据库
      const [result] = await conn.execute(
        "INSERT INTO books (title, author, publisher, publish_date, description, cover_path, epub_path, type_id, is_recommended) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)",
        [
          title,
          author,
          publisher,
          publishDate || null,
          description,
          coverPath,
          epubPath,
          typeId,
          isRecommended,
        ]
      );

      await conn.commit();

      res.json({
        code: 200,
        message: "电子书上传成功",
        data: { id: result.insertId },
      });
    } catch (error) {
      // 回滚事务
      await conn.rollback();

      // 删除已上传的文件
      if (epubPath) {
        try {
          require("fs").unlinkSync(epubPath);
        } catch (e) {
          console.error("删除epub文件失败:", e);
        }
      }
      if (coverPath) {
        try {
          require("fs").unlinkSync(coverPath);
        } catch (e) {
          console.error("删除封面文件失败:", e);
        }
      }

      // 打印详细错误堆栈和数据库相关信息
      console.error("上传电子书失败:", error);
      if (error && error.stack) {
        console.error("错误堆栈:", error.stack);
      }
      res.status(500).json({
        code: 500,
        message: error.message || "上传电子书失败",
      });
    } finally {
      conn.release();
    }
  }
);

// 获取推荐电子书列表
router.get("/recommended", async (req, res) => {
  try {
    const [rows] = await pool.execute(
      "SELECT b.*, t.type_name FROM books b LEFT JOIN book_types t ON b.type_id = t.id WHERE b.is_recommended = 1"
    );
    res.json({
      code: 200,
      data: rows.map((row) => formatBookData(row)),
    });
  } catch (error) {
    console.error("获取推荐电子书失败:", error);
    res.status(500).json({
      code: 500,
      message: "获取推荐电子书失败",
    });
  }
});

// 获取电子书详情
router.get("/:id", async (req, res) => {
  try {
    const [rows] = await pool.execute(
      "SELECT b.*, t.type_name FROM books b LEFT JOIN book_types t ON b.type_id = t.id WHERE b.id = ?",
      [req.params.id]
    );

    if (rows.length === 0) {
      return res.status(404).json({
        code: 404,
        message: "电子书不存在",
      });
    }

    const book = rows[0];
    const epub = await parseEpub(book.epub_path);
    const chapters = epub.flow.map((chapter, index) => {
      return {
        id: index,
        title: chapter.title || `第${index + 1}章`,
        href: chapter.href,
      };
    });

    res.json({
      code: 200,
      data: formatBookData(book, chapters),
    });
  } catch (error) {
    console.error("获取电子书详情失败:", error);
    res.status(500).json({
      code: 500,
      message: "获取电子书详情失败",
    });
  }
});

// 获取章节内容
router.get("/:id/chapter/:chapterId", async (req, res) => {
  try {
    const { id, chapterId } = req.params;
    const cacheKey = `book:${id}:chapter:${chapterId}`;

    // 尝试从缓存获取章节内容
    const cachedContent = await redisClient.get(cacheKey);
    if (cachedContent) {
      return res.json({
        code: 200,
        data: JSON.parse(cachedContent),
      });
    }

    // 从数据库获取电子书信息
    const [rows] = await pool.execute(
      "SELECT epub_path FROM books WHERE id = ?",
      [id]
    );
    if (rows.length === 0) {
      return res.status(404).json({
        code: 404,
        message: "电子书不存在",
      });
    }

    const epub = await parseEpub(rows[0].epub_path);
    const chapterData = await getChapterContent(epub, chapterId);

    // 缓存章节内容
    await redisClient.set(cacheKey, JSON.stringify(chapterData), {
      EX: 3600, // 缓存1小时
    });

    res.json({
      code: 200,
      data: chapterData,
    });
  } catch (error) {
    console.error("获取章节内容失败:", error);
    res.status(500).json({
      code: 500,
      message: error.message || "获取章节内容失败",
    });
  }
});

module.exports = router;
